﻿//-----------------------------------------------------------------------
// <copyright file="GeneralExtensions.cs" company="deixei.com">
//     Copyright (c) deixei.com. All rights reserved.
// </copyright>
// <author>Marcio Parente</author>
//---------------------------------------------------------------------
namespace Deixei.Web
{
    using Deixei.Common;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.CompilerServices;
    using System.Text;
    using System.Web.Mvc;
    using System.Web.Mvc.Html;
    using System.Web.Routing;
    using System.Web.Script.Serialization;

    /// <summary>
    /// General ASP.NET MVC Extensions
    /// </summary>
    public static class GeneralExtensions
    {

        public static MvcHtmlString Copyright(this HtmlHelper htmlHelper, string title)
        {
            // <p>&copy; <%: DateTime.Now.Year %> - My ASP.NET MVC Application</p>
            // Copyright (c) deixei.com. All rights reserved.
            string text = string.Format(WebResources.Copyright, DateTime.Now.Year, title);
            return new TagBuilder("p").Text(text).ToHtmlString();
        }

        public static MvcHtmlString MenuItem(this HtmlHelper htmlHelper, string linkText, string actionName, string controllerName)
        {
            TagBuilder item = new TagBuilder("li");
            
            item.Html(htmlHelper.ActionLink(linkText, actionName, controllerName).ToHtmlString());
            item.AddClass("active");
            //<li class="active"><%: Html.ActionLink("Home", "Index", "Home"). %></li>
            return item.ToHtmlString();
        }

        public static MvcHtmlString MenuBar(this HtmlHelper htmlHelper)
        {
            // <ul id="nav">
            //<li class="active"><%: Html.ActionLink("Home", "Index", "Home") %></li>
            // <li><%: Html.ActionLink("About", "About", "Home") %></li>
            // <li><%: Html.ActionLink("Contact", "Contact", "Home") %></li>
            // </ul>
            TagBuilder item = new TagBuilder("ul");
            item.Attribute("id", "menu");
            item.AddClass("nav");
            item.Append(
                htmlHelper.MenuItem("Home", "Index", "Home"),
                htmlHelper.MenuItem("About", "About", "Home"),
                htmlHelper.MenuItem("Contact", "Contact", "Home"),
                htmlHelper.MenuItem("Test", "Test", "Home"),
                htmlHelper.MenuItem("Values", "Values", "Home"));

            return item.ToHtmlString();
        }

        /// <summary>
        /// Contents the title.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <returns>Content Title string</returns>
        public static string ContentTitle(this HtmlHelper htmlHelper)
        {
            return htmlHelper.ViewData["__contentTitle"] as string;
        }

        /// <summary>
        /// Contents the title.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <param name="title">The title.</param>
        public static void ContentTitle(this HtmlHelper htmlHelper, string title)
        {
            htmlHelper.ViewData["__contentTitle"] = title;
        }

        /// <summary>
        /// Pages the title.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <returns>Page Title</returns>
        public static string PageTitle(this HtmlHelper htmlHelper)
        {
            return htmlHelper.ViewData["__pageTitle"] as string;
        }

        /// <summary>
        /// Pages the title.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <param name="title">The title.</param>
        public static void PageTitle(this HtmlHelper htmlHelper, string title)
        {
            htmlHelper.ViewData["__pageTitle"] = title;
        }

        /// <summary>
        /// HTMLs the page title.
        /// </summary>
        /// <param name="htmlHelper">The HTML helper.</param>
        /// <returns>Html Page Title</returns>
        public static string HtmlPageTitle(this HtmlHelper htmlHelper)
        {
            string str = htmlHelper.PageTitle();
            if (!string.IsNullOrEmpty(str))
            {
                return str;
            }

            string str2 = htmlHelper.ContentTitle();
            if (!string.IsNullOrEmpty(str2))
            {
                return string.Format(CommonResources.PageTitleWithContent.FormatUI(new object[] { str2 }));
            }

            return CommonResources.PageTitle;
        }

        #region "Helper methods"

        
        /// <summary>
        /// Texts the specified tag builder.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <param name="text">The text.</param>
        /// <returns>HTML Text Tag</returns>
        public static TagBuilder Text(this TagBuilder tagBuilder, string text)
        {
            CommonUtil.CheckForNull(tagBuilder, "tagBuilder");
            tagBuilder.SetInnerText(text);
            return tagBuilder;
        }

        /// <summary>
        /// To the HTML string.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <returns>HTML String</returns>
        public static MvcHtmlString ToHtmlString(this TagBuilder tagBuilder)
        {
            return tagBuilder.ToHtmlString(TagRenderMode.Normal);
        }

        /// <summary>
        /// To the HTML string.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <param name="renderMode">The render mode.</param>
        /// <returns>HTML String</returns>
        public static MvcHtmlString ToHtmlString(this TagBuilder tagBuilder, TagRenderMode renderMode)
        {
            CommonUtil.CheckForNull(tagBuilder, "tagBuilder");
            return MvcHtmlString.Create(tagBuilder.ToString(renderMode));
        }

        /// <summary>
        /// HTMLs the specified tag builder.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <param name="html">The HTML.</param>
        /// <returns>Html Tag</returns>
        public static TagBuilder Html(this TagBuilder tagBuilder, string html)
        {
            CommonUtil.CheckForNull(tagBuilder, "tagBuilder");
            tagBuilder.InnerHtml = html;
            return tagBuilder;
        }

        /// <summary>
        /// Appends the specified tag builder.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <param name="children">The children.</param>
        /// <returns>Append to HTML element</returns>
        public static TagBuilder Append(this TagBuilder tagBuilder, params object[] children)
        {
            CommonUtil.CheckForNull(tagBuilder, "tagBuilder");
            if (children.Length > 0)
            {
                StringBuilder builder = new StringBuilder(tagBuilder.InnerHtml ?? string.Empty);
                foreach (object obj2 in children)
                {
                    if (obj2 != null)
                    {
                        builder.Append(obj2.ToString());
                    }
                }

                tagBuilder.InnerHtml = builder.ToString();
            }

            return tagBuilder;
        }

        /// <summary>
        /// Appends the tag.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <param name="tagName">Name of the tag.</param>
        /// <param name="tagAction">The tag action.</param>
        /// <returns>Append to HTML element</returns>
        public static TagBuilder AppendTag(this TagBuilder tagBuilder, string tagName, Action<TagBuilder> tagAction)
        {
            CommonUtil.CheckForNull(tagBuilder, "tagBuilder");
            TagBuilder builder = new TagBuilder(tagName);
            if (tagAction != null)
            {
                tagAction(builder);
            }

            tagBuilder.Append(new object[] { builder });
            return tagBuilder;
        }

        /// <summary>
        /// Attributes the specified tag builder.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <param name="attributes">The attributes.</param>
        /// <returns>Attribute Tag</returns>
        public static TagBuilder Attribute(this TagBuilder tagBuilder, object attributes)
        {
            return tagBuilder.Attribute(attributes, true);
        }

        /// <summary>
        /// Attributes the specified tag builder.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <param name="attributes">The attributes.</param>
        /// <param name="replaceExisting">if set to <c>true</c> [replace existing].</param>
        /// <returns>Attribute Tag</returns>
        public static TagBuilder Attribute(this TagBuilder tagBuilder, object attributes, bool replaceExisting)
        {
            CommonUtil.CheckForNull(tagBuilder, "tagBuilder");
            if (attributes != null)
            {
                RouteValueDictionary dictionary = new RouteValueDictionary(attributes);
                if (dictionary.ContainsKey("addClass"))
                {
                    tagBuilder.AddClass(dictionary["addClass"] as string);
                    dictionary.Remove("addClass");
                }

                tagBuilder.MergeAttributes<string, object>(dictionary, replaceExisting);
            }

            return tagBuilder;
        }

        /// <summary>
        /// Attributes the specified tag builder.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <param name="attribute">The attribute.</param>
        /// <param name="attributeValue">The attribute value.</param>
        /// <returns>Attribute Tag</returns>
        public static TagBuilder Attribute(this TagBuilder tagBuilder, string attribute, string attributeValue)
        {
            return tagBuilder.Attribute(attribute, attributeValue, true);
        }

        /// <summary>
        /// Attributes the specified tag builder.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <param name="attribute">The attribute.</param>
        /// <param name="attributeValue">The attribute value.</param>
        /// <param name="replaceExisting">if set to <c>true</c> [replace existing].</param>
        /// <returns>Attribute Tag</returns>
        public static TagBuilder Attribute(this TagBuilder tagBuilder, string attribute, string attributeValue, bool replaceExisting)
        {
            CommonUtil.CheckForNull(tagBuilder, "tagBuilder");
            CommonUtil.CheckStringForNullOrEmpty(attribute, "attribute");
            tagBuilder.MergeAttribute(attribute, attributeValue, replaceExisting);
            return tagBuilder;
        }

        /// <summary>
        /// Adds the class.
        /// </summary>
        /// <param name="tagBuilder">The tag builder.</param>
        /// <param name="cssClass">The CSS class.</param>
        /// <returns>Add Class to HTML element</returns>
        public static TagBuilder AddClass(this TagBuilder tagBuilder, string cssClass)
        {
            CommonUtil.CheckForNull(tagBuilder, "tagBuilder");
            tagBuilder.AddCssClass(cssClass);
            return tagBuilder;
        }

        #endregion
    }
}
